import multiprocessing
import shlex

import subprocess

from watcher import ModuleWatcher
import logging
from logging import error, debug, info
import sys
import diagnose
import json

if __name__ == '__main__':
    FORMAT = '[%(levelname)-5s]%(process)5d:%(asctime)-8s %(filename)s:%(lineno)d %(message)s'
    DATEFORMAT = '%H:%M:%S'
    logging.basicConfig(level=logging.DEBUG, format=FORMAT, datefmt=DATEFORMAT, filename='server.log')

    debug(sys.argv)

    if len(sys.argv) == 1:
        error('error run argv')
    elif sys.argv[1] == 'worker':
        import redis

        mw = ModuleWatcher()
        mw.watch_module('diagnose')
        mw.start_watching()

        debug('worker running')
        pool = redis.ConnectionPool(host='localhost', port=6379, db=0)
        r = redis.Redis(connection_pool=pool)
        while True:
            taskstr = r.blpop('diagnose_tasks')[1].decode()
            task = json.loads(taskstr)
            assert task['file_name']
            fname = task['file_name']
            debug(fname)
            result = diagnose.gen_diagnose(fname)
            task['result'] = result
            distkey = 'finished_tasks'
            if 'dist' in task:
                distkey = task['dist']
            r.rpush(distkey, json.dumps(task))
    elif sys.argv[1] == 'server':
        import redis
        processList = []
        # THREADS = multiprocessing.cpu_count()
        THREADS = 3
        pool = redis.ConnectionPool(host='localhost', port=6379, db=0)
        # r = redis.Redis(connection_pool=pool)
        # r.flushall()
        # THREADS = 1
        call_str = 'python3 %s %s' % (sys.argv[0], 'handler')
        subprocess.Popen(shlex.split(call_str))
        call_str = 'python3 %s' % ('deploy.py')
        subprocess.Popen(shlex.split(call_str))
        call_str = 'python3 %s %s' % (sys.argv[0], 'worker')
        for i in range(THREADS):
            processList.append(subprocess.Popen(shlex.split(call_str)))
        while 1:
            for p in processList:
                try:
                    returncode = p.wait(10)
                    if returncode != None:
                        error('process returned err')
                    processList.remove(p)
                    processList.append(subprocess.Popen(shlex.split(call_str)))
                    debug('add thread')
                except subprocess.TimeoutExpired:
                    debug('time out')
                    pass
    elif sys.argv[1] == 'handler':
        debug('task handler running ...')
        import redis
        from main import FundusImage
        pool = redis.ConnectionPool(host='localhost', port=6379, db=0)
        r = redis.Redis(connection_pool=pool)
        while True:
            x = r.blpop('finished_tasks')
            retinfo = x[1].decode()
            debug('handler')
            debug(retinfo)
            task_result = json.loads(retinfo)
            debug(task_result)
            image_record = FundusImage.get(FundusImage.id == int(task_result['id']))
            image_record.result_raw = task_result['result']
            image_record.save()

